# -*- coding:utf-8 -*- 
from .void_pb2 import Void
from .profile import profile_callmethod, get_profile
from .channel import Controller, Callback

__all__ = [
        'Proxy',
    ]

class Proxy(object):
    def __init__(self, stub):
        self._stub = stub

    def __dir__(self):
        return dir(self._stub)

    def __getattr__(self, name):
        def call(method, request):
            controller = Controller(None)
            callback = Callback()
            method(controller, request, callback)
            return callback.response

        if get_profile():
            call = profile_callmethod(
                    '.'.join((self._stub.GetDescriptor().name, name)))(call)

        req_cls = self._stub.GetRequestClass(
                self._stub.GetDescriptor().FindMethodByName(name))

        def rpc_method(*a, **kw):
            if (not a) and (not kw):
                req = Void()
                return call(getattr(self._stub, name), req)
            if a:
                if len(a) != 1:
                    raise TypeError('%s() takes at most 1 argument (%d given)' % (name, len(a)))
                return call(getattr(self._stub, name), a[0])
            if kw:
                req = req_cls(**kw)
                return call(getattr(self._stub, name), req)
            raise RuntimeError('Some error occurred.')

        return rpc_method

